package com.yjck.ijpay.loginCode;


import java.time.LocalDateTime;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 缓存系统中的验证码
 */
public class CaptchaCodeManager {
    //高并发
    //ConcurrentHashMap 允许多个修改操作并发进行，其关键在于使用了锁分离技术
    //首先将数据分成一段一段的存储，然后给每一段数据配一把锁，当一个线程占用锁访问其中一个段数据的时候，其他段的数据仍能被其他线程访问。
    private static ConcurrentHashMap<String, CaptchaItem> captchaCodeCache = new ConcurrentHashMap<>();

    /**
     * 添加到缓存
     *
     * @param phoneNumber 电话号码
     * @param code        验证码
     */
    public static boolean addToCache(String phoneNumber, String code) {

        //已经发过验证码且验证码还未过期
        if (captchaCodeCache.get(phoneNumber) != null) {
            if (captchaCodeCache.get(phoneNumber).getExpireTime().isAfter(LocalDateTime.now())) {
                return false;
            } else {
                //存在但是已过期，删掉
                captchaCodeCache.remove(phoneNumber);
            }
        }

        CaptchaItem captchaItem = new CaptchaItem();
        captchaItem.setPhoneNumber(phoneNumber);
        captchaItem.setCode(code);
        // 有效期为1分钟
        captchaItem.setExpireTime(LocalDateTime.now().plusMinutes(1));

        captchaCodeCache.put(phoneNumber, captchaItem);

        return true;
    }

    public static void main(String[] args) {
        String captcha = getCachedCaptcha("13526");
        System.out.println("验证码："+captcha);
        boolean addToCache = addToCache("13526", "123");
        System.out.println("添加："+addToCache);
        boolean addToCache1 = addToCache("13526", "奥术大师多");
        if(!addToCache1){
            System.out.println("验证码未超时1分钟，不能添加");
        }
        String captcha1 = getCachedCaptcha("13526");
        System.out.println("添加之后验证码："+captcha1);
    }
    /**
     * 获取缓存的验证码
     *
     * @param phoneNumber 关联的电话号码
     * @return 验证码
     */
    public static String getCachedCaptcha(String phoneNumber) {
        //没有这个电话记录
        if (captchaCodeCache.get(phoneNumber) == null)
            return null;

        //有电话记录但是已经过期
        if (captchaCodeCache.get(phoneNumber).getExpireTime().isBefore(LocalDateTime.now())) {
            return null;
        }

        return captchaCodeCache.get(phoneNumber).getCode();
    }
}
